<?php
declare (strict_types = 1);

namespace app\api\model;

use app\common\model\Config;
use app\common\self\SelfRedis;
use app\mall\model\Activity;
use app\mall\model\Goods;
use app\video\model\Video;
use app\view\model\Ad;
use think\facade\Db;

error_reporting(0);

/**
 * @mixin \think\Model
 */
class WxApi
{
    public $page = '';//分页数据
    public $count = '';//数据总数
    public $error = '';//报错
    public $qrurl = 'https://res.wx.qq.com/op_res/BbVNeczA1XudfjVqCVoKgfuWe7e3aUhokktRVOqf_F0IqS6kYR--atCpVNUUC3zr';//直播认证二维码
    public $templates = [
        'mGK47YKcHJCeCKnujjn_YcxgdrIXISlEJwtu826d1wA'=>[
            'thing1'=>['value'=>'order_sn'],//O20200712100000
            'time2'=>['value'=>'date'],//2015年01月05日
            'thing3'=>['value'=>'titel'],//大牌促销
            'amount4'=>['value'=>'amount'],//￥100.00
            'thing5'=>['value'=>'msg'],//买它！
        ],
        'FddT6-1bVu2lfiggUR7FVmS0mwrvTlGIgksy6xh94XE'=>[
            'character_string4'=>['value'=>'order_sn'],
            'thing5'=>['value'=>'goods_name'],
            'amount2'=>['value'=>'total_amount'],
            'amount6'=>['value'=>'pay_amount'],
            'time7'=>['value'=>'date'],
        ],
    ];

    public $wxErrorCode = [
        -1=>'系统错误',
        1=>'未创建直播间',
        1003=>'商品id不存在',
        47001=>'入参格式不符合规范',
        200002=>'入参错误',
        300001=>'禁止创建/更新商品 或 禁止编辑&更新房间',
        300002=>'名称长度不符合规则',
        300006=>'图片上传失败（如：mediaID过期）',
        30002=>'此房间号不存在',
        300023=>'房间状态 拦截（当前房间状态不允许此操作）',
        300024=>'商品不存在',
        300025=>'商品审核未通过',
        300026=>'房间商品数量已经满额',
        300027=>'导入商品失败',
        300028=>'房间名称违规',
        300029=>'主播昵称违规',
        300030=>'主播微信号不合法',
        300031=>'直播间封面图不合规',
        300032=>'直播间分享图违规',
        300033=>'添加商品超过直播间上限',
        300034=>'主播微信昵称长度不符合要求',
        300035=>'主播微信号不存在',
        300036=>'主播微信号未实名认证',
        300037=>'购物直播频道封面图不合规',
        300038=>'未在小程序管理后台配置客服',
        9410000=>'直播间列表为空',
        9410001=>'获取房间失败',
        9410002=>'获取商品失败',
        9410003=>'获取回放失败',
    ];

    /*
     * 小程序二维码
     */
    public function wxaCode($user){
        try{
            $data = Input('post.');
            if(empty($user)) exception('找不到该用户!');
            if(empty($data['type'])) exception('ERR：缺少分享类型');
            if(empty($data['page'])) exception('ERR：缺少分享地址');
            $user = $user->toArray();
            $title = $name = '';
            if($data['type'] <= 3){
                if(empty($data['id'])||!is_numeric($data['id'])) exception('ERR：缺少分享数据');
                if($data['type'] == 1){ #商品分享
                    $title = '为你推荐一件商品';
                    $name = "/qrcode/commodity_{$user['invite_code']}_{$data['id']}.png";
                    $share = (new Goods())->getShareInfo($data['id']);
                    if(!is_array($share)) exception('ERR：'.$share);
                }elseif($data['type'] == 2){ #活动分享
                    $title = '邀请你参加拼团活动';
                    $name = "/qrcode/activity_{$user['invite_code']}_{$data['id']}.png";
                    $shareGroup = (new Activity())->getShareGroup($data['id'],$user['id']);
                    if(!is_array($shareGroup)) exception('ERR：'.$shareGroup);
                }elseif($data['type'] == 3){ #视频分享
                    $name = "/qrcode/video_{$user['invite_code']}_{$data['id']}.png";
                    $shareVideo = (new Video())->getShareInfo($data['id']);
                    if(!is_array($shareVideo)) exception('ERR：'.$shareVideo);
                    $title = $shareVideo['title']??'';
                    $user = ['id'=>$shareVideo['uid'],'nickname'=>$shareVideo['nickname'],'avatarurl'=>$shareVideo['avatarurl'],'invite_code'=>$shareVideo['invite_code']];
                }else exception('ERR：分享类型错误');
            }elseif($data['type'] == 4){ #个人海报分享
                $title = '邀请你加入'.getAppNmae().'分享赚';
                $name = "/qrcode/self_{$user['invite_code']}.png";
                $model = new Ad();
                $type = 'poster_share';
                $where = ['type_key'=>$type,'is_delete'=>0,'show'=>1];
                if($model->where($where)->count()){
                    $poster = $model->where($where)->order(\think\facade\Db::raw('RAND()'))->find();
                    if(!empty($poster['img_url'])) $share_img = $poster['img_url'];
                }
                //Db::name('view_poster')->where(['status'=>1])->order(Db::raw('RAND()'))->find();
            }else exception('ERR：分享类型错误');
            //封装输出数据
            $ret = [
                'nickname' => $user['nickName']??$user['nickname'],
                'avatarurl' => $user['avatarurl'],
                'code' => $user['invite_code'],
                'title' => $title,
                'qr_code' => getApiDominUrl(config('static.read_img').$name),
                'share_img' => !empty($share_img) ? getHostDominUrl($share_img) : '',
                'goods' => [],
                'group' => [],
                'video' => [],
            ];
            //分享商品信息
            if(!empty($share)&&is_array($share)) $ret['goods'] = [
                'amount' => $share['default_discount_price'],
                'title' => (mb_strlen($share['title'],'utf-8')>20 ? mb_substr($share['title'],0,20,'utf-8') : $share['title']),
                'title1' => (mb_strlen($share['title'],'utf-8')>20 ? mb_substr($share['title'],20,mb_strlen($share['title'],'utf-8'),'utf-8') : ''),
                'cover' => $share['share'],
            ];
            //分享活动
            if(!empty($shareGroup)&&is_array($shareGroup)) $ret['group'] = [
                'name'=>$shareGroup['name'],
                'title'=>mb_substr($shareGroup['title'],0,16,'utf-8'),
                'share'=>$shareGroup['share'],
                //$ret['title'] = '邀请你参加'.$shareGroup['name'].'拼团活动';
            ];
            //分享视频
            if(!empty($shareVideo)&&is_array($shareVideo)) $ret['group'] = [
                'cover'=>$shareVideo['cover'],
                'title'=>$shareVideo['title'],
            ];
            if(file_exists(app()->getRootPath().'public/uploads'.$name)){
                return $ret; #如果已存在该分享海报则直接输出
            }
            //请求小程序二维码接口
            $query = '';
            if(!empty($user['invite_code'])) $query = !empty($query)? $query.'&code='.$user['invite_code'] : 'code='.$user['invite_code'];
            if(!empty($user['id'])) $query = !empty($query)? $query.'&uid='.$user['id'] : 'uid='.$user['id'];
            if(!empty($data['id'])) $query = !empty($query)? $query.'&id='.$data['id'] : 'id='.$data['id'];
            //$query = !empty($query)? $query.'&shareIt=1' : 'shareIt=1';
            $access_token = (new Config())->getAccessToken();
            $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$access_token}";
            $req = [
                'scene' => $query,
                'page' => $data['page'],
                'is_hyaline' => true
            ];
            $header[] = 'Content-Type:application/json';
            $header[] = 'Content-Length:'.strlen(json_encode($req));
            $code = curlPost($url, json_encode($req), $header);
            $errcode = !empty($code) ? json_decode($code,true) : [];
            if(!empty($errcode)&&isset($errcode['errcode'])) exception($errcode['errcode'].':'.$errcode['errmsg']);
            $res = file_put_contents(app()->getRootPath().'public/uploads'.$name, $code); //保存二维码
            return $ret;
        }catch (\Exception $e){
            if(stristr($e->getMessage(),'SQLSTATE')){
                $this->error = '数据走丢了，请稍后再试！';
            }else $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 我的卡片分享
     */
    public function myCardShare($user){
        try{
            if(empty($user)) exception('找不到该用户!');
            $ret['title'] = '邀请你加入'.getAppNmae().'分享赚';
            $ret['share_img'] = '';
            $model = new Ad();
            $type = 'poster_share';
            $where = ['type_key'=>$type,'is_delete'=>0,'show'=>1];
            if($model->where($where)->count()){
                $poster = $model->where($where)->order(\think\facade\Db::raw('RAND()'))->find();
                if(!empty($poster['img_url'])) $ret['share_img'] = getHostDominUrl($poster['img_url']);
            }
            return $ret;
        }catch (\Exception $e){
            if(stristr($e->getMessage(),'SQLSTATE')){
                $this->error = '数据走丢了，请稍后再试！';
            }else $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 小程序消息订阅模板
     */
    public function wxaTemplate($user,$data = []){
        try{
            $data = is_array($data) && count($data) > 0 ? $data : Input('post.');
            if(empty($data['tid'])) exception('找不到该用户!');
            if(!isset($this->templates[$data['tid']]) || empty($this->templates[$data['tid']])) exception('找不到模板!');
            $access_token = (new Config())->getAccessToken();
            $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={$access_token}";
            $req = [
                'access_token'=>$access_token,
                'touser'=>$user->openid,
                'template_id'=>$data['tid'],
                'page'=>$data['page']??'',
                'data'=>[],
                'miniprogram_state'=>'developer'
            ];
            foreach($this->templates[$data['tid']] as $k=>$v){
                if(isset($data[$v['value']])) $req['data'][$k]=['value'=>$data[$v['value']]];
            }
            $header[] = 'Content-Type:application/json';
            $header[] = 'Content-Length:'.strlen(json_encode($req));
            $ret = curlPost($url,json_encode($req),$header);
            return $ret;
        }catch (\Exception $e){
            if(stristr($e->getMessage(),'SQLSTATE')){
                $this->error = '数据走丢了，请稍后再试！';
            }else $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 过滤敏感词
     */
    public function msgSecCheck($id){
        try{
            $data = Input('post.');
            if(empty($data['text'])) exception('数据不能为空!');
            $access_token = (new Config())->getAccessToken();
            $url = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token={$access_token}";
            $req = [
                //'access_token'=>$access_token,
                'content'=>$data['text'],
            ];
            $header[] = 'Content-Type:application/json';
            $header[] = 'Content-Length:'.strlen(json_encode($req));
            $ret = curlPost($url,json_encode($req),$header);
            return [$ret,$access_token];
        }catch (\Exception $e){
            if(stristr($e->getMessage(),'SQLSTATE')){
                $this->error = '数据走丢了，请稍后再试！';
            }else $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 导师微信
     */
    public function tutorWechat(){
        try{
            $data = (new Config())->toData('business');
            $info = [
                'wechat'=>$data['teacher'],
                'name'=>'喵导师',
                'avatarurl'=>'https://admin.miaommei.com/uploads/user/20200620/fb4a6a52568e28316c95292a96b51556.jpg',
            ];
            return $info;
        }catch (\Exception $e){
            if(stristr($e->getMessage(),'SQLSTATE')){
                $this->error = '数据走丢了，请稍后再试！';
            }else $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 创建直播房间
     */
    public function createLiveBroadcast($data){
        try{
            if(empty($data['title'])) exception('请填写直播间名称!');
            if(empty($data['name'])) exception('请填写主播昵称!');
            if(empty($data['wechat'])) exception('请填写主播微信号!');
            if(empty($data['coverImg'])) exception('请先选择直播背景图!');
            if(empty($data['shareImg'])) exception('请先选择直播分享图!');
            if(empty($data['type'])) exception('请先选择直播类型!');
            if(empty($data['start'])||empty($data['end'])) exception('请先选择直播开始/结束时间!');

            $access_token = (new Config())->getAccessToken();

            $url1 = 'https://api.weixin.qq.com/wxaapi/broadcast/room/create?access_token='.$access_token;
            $req = [
                'name'=> $data['title'], //直播间名字，最短3个汉字，最长17个汉字，1个汉字相当于2个字符
                'anchorName'=> $data['name'], //主播昵称，最短2个汉字，最长15个汉字，1个汉字相当于2个字符
                'anchorWechat'=> $data['wechat'], //主播微信号，如果未实名认证，需要先前往“小程序直播”小程序进行实名验证
                'coverImg'=> $data['coverImg'], //背景图，填入mediaID（mediaID获取后，三天内有效）；
                'shareImg'=> $data['shareImg'], //分享图，填入mediaID（mediaID获取后，三天内有效）；
                'feedsImg'=> ($data['feedsImg']??''), //非必填 购物直播频道封面图，填入mediaID（mediaID获取后，三天内有效）；
                'startTime'=> $data['start'], //直播计划开始时间（开播时间需要在当前时间的10分钟后 并且 开始时间不能在 6 个月后）
                'endTime'=> $data['end'], //直播计划结束时间（开播时间和结束时间间隔不得短于30分钟，不得超过24小时）
                'closeGoods'=> ($data['type']==1 ? 0 : 1), //是否关闭货架 【0：开启，1：关闭】（若关闭，直播开始后不允许开启）
                'screenType'=> ($data['screen']??0), //横屏、竖屏 【1：横屏，0：竖屏】（横屏：视频宽高比为16:9、4:3、1.85:1 ；竖屏：视频宽高比为9:16、2:3）
                'closeLike'=> ($data['like']??0), //是否关闭点赞 【0：开启，1：关闭】（若关闭，直播开始后不允许开启）
                'closeReplay'=> ($data['replay']??0), //非必填 是否关闭回放 【0：开启，1：关闭】默认关闭回放
                'closeComment'=> ($data['comment']??0), //是否关闭评论 【0：开启，1：关闭】（若关闭，直播开始后不允许开启）
                'closeShare'=> ($data['share']??0), //非必填 是否关闭分享 【0：开启，1：关闭】默认开启分享（直播开始后不允许修改）
                'isFeedsPublic'=> ($data['isfeeds']??0), //非必填 是否开启官方收录 【1: 开启，0：关闭】，默认开启收录
                'type'=> 0, //直播间类型 【1: 推流，0：手机直播】
                'closeKf'=> 1, //非必填 是否关闭客服 【0：开启，1：关闭】 默认关闭客服
            ];
            $header[] = 'Content-Type:application/json';
            $header[] = 'Content-Length:'.strlen(json_encode($req));
            $ret = curlPost($url1,json_encode($req),$header);
            Db::name('wechat_api_log')->insert(['uid'=>$data['uid'],'request'=>json_encode($req),'response'=>$ret]);
            $info = json_decode($ret,true);
            if(!empty($info['errcode'])){
                if($info['errcode'] == 300036) $err = 300036;
                else $err = isset($this->wxErrorCode[$info['errcode']])?$this->wxErrorCode[$info['errcode']]:'小程序服务忙，请稍后再试！';
                exception($err);
            }
            return $info;
        }catch (\Exception $e){
            $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 获取直播房间列表/获取回放视频源
     */
    public function getLiveList($data){
        try{
            $access_token = (new Config())->getAccessToken();

            $url1 = 'https://api.weixin.qq.com/wxa/business/getliveinfo?access_token='.$access_token;
            $req = [
                'start'=> ($data['start']??0), //起始拉取房间，start = 0 表示从第 1 个房间开始拉取
                'limit'=> ($data['limit']??100), //每次拉取的个数上限，不要设置过大，建议 100 以内
            ];
            if(!empty($data['room_id'])){
                $req['action'] = 'get_replay';
                $req['room_id'] = $data['room_id'];//存在房间号则取回放视频源
            }
            $header[] = 'Content-Type:application/json';
            $header[] = 'Content-Length:'.strlen(json_encode($req));
            $ret = curlPost($url1,json_encode($req),$header);
            #Db::name('wechat_api_log')->insert(['uid'=>$data['uid'],'request'=>json_encode($req),'response'=>$ret]);
            $info = json_decode($ret,true);
            if(!empty($info['errcode'])) exception(isset($this->wxErrorCode[$info['errcode']])?$this->wxErrorCode[$info['errcode']]:'小程序服务忙，请稍后再试！');
            return $info;
        }catch (\Exception $e){
            $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 获取直播房间列表/获取回放视频源
     */
    public function addGoods($data){
        try{
            if(empty($data['room_id'])||!is_numeric($data['room_id'])) exception('请选择要直播带货的直播间!');
            if(empty($data['goods'])||!is_array($data['goods'])) exception('请选择加入直播间的商品!');
            $access_token = (new Config())->getAccessToken();

            $url = 'https://api.weixin.qq.com/wxaapi/broadcast/room/addgoods?access_token='.$access_token;
            $req = [
                'ids'=> $data['goods'], //"ids": [1150, 1111],  // 数组列表，可传入多个，里面填写 商品 ID
                'roomId'=> $data['room_id'], //房间id
            ];
            $header[] = 'Content-Type:application/json';
            $header[] = 'Content-Length:'.strlen(json_encode($req));
            $ret = curlPost($url,json_encode($req),$header);
            $info = json_decode($ret,true);
            Db::name('wechat_api_log')->insert(['uid'=>$data['uid'],'request'=>json_encode($req),'response'=>$ret]);
            if(!empty($info['errcode'])) exception(isset($this->wxErrorCode[$info['errcode']])?$this->wxErrorCode[$info['errcode']]:'小程序服务忙，请稍后再试！');
            return $info;
        }catch (\Exception $e){
            $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 上传临时素材文件 获取到 素材id 需要存储
     * @params $data   type 表示 文件类型  img 文件路劲
     */
    public function uploadImg($data){
        try{
            $access_token = $this->getToken();
            // 上传的操作  access_token 和 type 必须在参数数据里面
            $url1 = "https://api.weixin.qq.com/cgi-bin/media/upload";
            if(empty($data['img'])) exception('请选择图片！');
            $req = [
                'access_token'=>$access_token,
                'type'=> ($data['type']??'image'), //媒体文件类型，分别有图片（image）、语音（voice）、视频（video）和缩略图（thumb）
                'media'=>  new \CURLFile($data['img']), //图片文件, 此处是路劲
            ];
            $ret = curlFormPost($url1,$req, false);
            Db::name('wechat_api_log')->insert(['uid'=>$data['uid']??0,'request'=>json_encode($req),'response'=>json_encode($ret)]);
            if(!empty($ret['media_id'])) return $ret['media_id'];
            exception($ret['errmsg']??'向微信提交图片失败！');
        }catch (\Exception $e){
            $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 获取微信token
     */
    public function getToken(){
        $sr = new SelfRedis();
        $sr->redis->delete('access_token');
        $access_token = $sr->redis->get('access_token');
        if(empty($access_token)){
            $config = Config::where(['type'=>'wechat'])->value('content');
            $wachat = json_decode($config,true);
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$wachat['appid']}&secret={$wachat['appsecret']}";
            $ret = curlGet($url);
            $retData = json_decode($ret,true);

            if(!empty($retData['access_token'])) $sr->redis->set('access_token',$retData['access_token'],7200);
            $access_token = $retData['access_token'];
        }
        return $access_token;
    }
}
